/*
 * Project it.battlehorse.rcp.tools
 * Created on Nov 18, 2005
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * A copy of the LGPL is available also at
 * http://www.gnu.org/copyleft/lesser.html
 * 
 */
package it.battlehorse.rcp.tools.views.actorlist;

import it.battlehorse.rcp.sl.annot.Injected;
import it.battlehorse.rcp.sl.annot.Serviceable;
import it.battlehorse.rcp.tools.actors.ActorDescriptor;
import it.battlehorse.rcp.tools.actors.IActorConstants;

import org.apache.commons.logging.Log;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

/**
 * Defines the view which contains the list of the available actors
 * 
 * @author battlehorse
 * @since Nov 18, 2005
 */
@Serviceable
public class ActorListView extends ViewPart implements IActorConstants {
	
	/**
	 * The id of this view, whose value if {@value }
	 */
	public static final String ID_VIEW = "it.battlehorse.rcp.tools.views.actorlist.ActorListView";

	private Action openAction;
	
	private TableViewer viewer;
	
	/* A logger */
	private Log log;

	/**
	 * Injects a reference to a valid logger
	 * 
	 * @param log a logger
	 */
	@Injected
	public void setLog(Log log) {
		this.log = log;
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento)
	 */
	@Override public void init(IViewSite site, IMemento memento) throws PartInitException {
		super.init(site, memento);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	@Override public void createPartControl(Composite parent) {
		createActions();
		
		viewer = new TableViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
		
		Table t = viewer.getTable();
		new TableColumn(t,SWT.LEFT).setText("Actors");
		
        viewer.setContentProvider(new ActorListContentProvider());
        viewer.setLabelProvider(new ActorListLabelProvider());
        viewer.setInput("root");
        
        viewer.addDoubleClickListener(new ActorListDblClickListener(this));
        
		for (TableColumn col : t.getColumns()) 
			 col.pack();
        
        createContextMenu();
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
	 */
	@Override public void setFocus() {
		viewer.getControl().setFocus();
	}
			
	/**
	 * Creates the actions associated with this view
	 *
	 */
    private void createActions() {
    	openAction = new Action("Open") {
    		@Override
			public void run() {  
    			if (viewer.getSelection() != null)
    			openActor(viewer.getSelection());
    		}
    	};
    	openAction.setImageDescriptor(
    			PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD));
   }	
	
    /**
     * Creates the context menu which defines the available actions for every
     * actor defined in the platform
     *
     */
	private void createContextMenu() {
		// Create menu manager.
        MenuManager menuMgr = new MenuManager();
           menuMgr.setRemoveAllWhenShown(true);
           menuMgr.addMenuListener(new IMenuListener() {
                   public void menuAboutToShow(IMenuManager mgr) {
                           fillContextMenu(mgr);
                   }
           });
           
        // Create menu.
        Menu menu = menuMgr.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
           
         // Register menu for extension.
        getSite().registerContextMenu(menuMgr, viewer);		
	}
	
	/**
	 * Populates the context menu
	 * 
	 * @param mgr
	 */
	private void fillContextMenu(IMenuManager mgr) {
        mgr.add(openAction);
        mgr.add(new Separator());
        mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));		
	}
	
    /**
     * Opens the selected actor in the current actors list. If the actor is already open
     * then it is given focus.
     * 
     * @param selection the selection which describes the actor to be opened.
     */
    public void openActor(ISelection selection) {
		if (selection instanceof IStructuredSelection) {
			IStructuredSelection structSel = (IStructuredSelection) selection;
			ActorDescriptor conf = (ActorDescriptor) structSel.getFirstElement();
			if (conf != null) {

				try {
					
					String viewId = conf.getViewId();				
					PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(viewId);
				}
				catch(Exception e) {
					log.error("Error while opening the selected Actor : " + e.getMessage(),e);
					MessageDialog.openError(
							PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
							"Error!",
							"Error while opening the selected Actor in the editor : \n" +
							e.getClass().getName() + "\n" + e.getMessage());
					
				}
			}

		}
    }

}
